package br.com.usjt.sge.web.bean;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;

import br.com.usjt.sge.complemento.Endereco;
import br.com.usjt.sge.complemento.EnderecoRN;
import br.com.usjt.sge.complemento.Telefone;
import br.com.usjt.sge.complemento.TelefoneRN;
import br.com.usjt.sge.correios.Cep;
import br.com.usjt.sge.correios.CepRN;
import br.com.usjt.sge.estacionamento.Estacionamento;
import br.com.usjt.sge.estacionamento.EstacionamentoRN;
import br.com.usjt.sge.usuario.Usuario;
import br.com.usjt.sge.usuario.UsuarioRN;
import br.com.usjt.sge.util.ContextoUtil;
import br.com.usjt.sge.util.CriptografiaUtil;
import br.com.usjt.sge.util.RNException;
import br.com.usjt.sge.util.ValidaCPFCNPJ;
import br.com.usjt.sge.web.ContextoBean;

@ManagedBean(name = "estacionamentoBean")
@SessionScoped
public class EstacionamentoBean {

	private Estacionamento estacionamento = new Estacionamento();
	private Telefone prim_telefone = new Telefone();
	private Endereco endereco = new Endereco();
	private Usuario usuario = new Usuario();
	private List<Estacionamento> lista = null;
	private String confirmarSenha;
	private String destino;
	private String complemento;
	private String cep;
	private String cnpj;
	private String numero;
	private String enderecoEstac;
	private String telefone;
	private String senhaCriptografada;
	private Integer totalVaga;
	private Integer ocupadas;
	private Integer livres;
	private boolean modalVaga;
	private int livre = 99;
	private int ocupada = 1;
	private int statusAnterior = 0;
	

	public String novo() {
		this.destino = "estacionamentoSucesso";
		this.usuario = new Usuario();
		this.usuario.setAtivo(true);
		return "estacionamento";

	}

	public String estacionamentoLogado() {
		FacesContext context = FacesContext.getCurrentInstance();
		ContextoBean contextBean = ContextoUtil.getContextoBean();
		Usuario usuarioLogado = contextBean.getUsuarioLogado();
		Set<String> permisao = usuarioLogado.getPermissao();

		// ocupadas = totalVagas - livres;
		// lista.add(totalVagas);
		// lista.add(livres);
		// lista.add(ocupadas);
		// }

		EstacionamentoRN estacioanamentoRN = new EstacionamentoRN();
		if (permisao.equals("ROLE_ADMINISTRADOR")) {
			this.estacionamento = estacioanamentoRN
					.buscarPorUsuario(usuarioLogado.getCodigo());
			return "meuEstacionamento";
		} else {
			FacesMessage facesMessage = new FacesMessage(
					"Não existe estacionamento  cadastrado para este usuário");
			context.addMessage(null, facesMessage);

			return null;

		}

	}

	public String salvar() throws IOException {

		FacesContext context = FacesContext.getCurrentInstance();

		boolean cnpjConsultado = getValidaCnpj();

		if (!cnpjConsultado) {

			FacesMessage facesMessage = new FacesMessage(
					FacesMessage.SEVERITY_ERROR, "CNPJ inválido.",
					"Informe um CNPJ válido para o cadastro.");
			context.addMessage(null, facesMessage);
			return null;
		}

		String senha = this.usuario.getSenha();

		if (senha != null && senha.trim().length() > 0
				&& !senha.equals(this.confirmarSenha)) {

			FacesMessage facesMessage = new FacesMessage(
					"A senha não foi confirmada corretamente");
			context.addMessage(null, facesMessage);

			return null;
		}

		if (senha != null && senha.trim().length() == 0) {

			this.usuario.setSenha(this.senhaCriptografada);

		} else {

			try {

				String senhaCripto = CriptografiaUtil.criptografar(senha);
				this.usuario.setSenha(senhaCripto);

			} catch (NoSuchAlgorithmException e) {

				FacesMessage facesMessage = new FacesMessage(
						"Não foi possível criptografar a senha do usuário. Erro: "
								+ e.getMessage());
				context.addMessage(null, facesMessage);
				return null;
			}

		}

		ValidaCPFCNPJ cnpjValida = new ValidaCPFCNPJ();
		Long cnpj = cnpjValida.parseLongCnpj(this.cnpj);
		estacionamento.setCpfcnpj(cnpj);

		EnderecoRN enderecoRN = new EnderecoRN();
		endereco.setNumero(Integer.parseInt(numero));
		endereco.setComplemento(complemento);
		estacionamento.setEndereco(endereco);
		enderecoRN.salvar(endereco);

		UsuarioRN usuarioRN = new UsuarioRN();
		this.usuario.setNome(this.estacionamento.getNome_fantasia());
		this.usuario.setCpf(Long.toString(this.estacionamento.getCpfcnpj()));
		this.usuario.setEmail(this.estacionamento.getEmail());
		estacionamento.setUsuario(usuario);
		usuarioRN.salvarEstacionamento(usuario);

		TelefoneRN telefoneRN = new TelefoneRN();
		estacionamento.setTelefone(this.prim_telefone);
		telefoneRN.salvar(prim_telefone);

		EstacionamentoRN estacionamentoRN = new EstacionamentoRN();
		estacionamentoRN.salvar(estacionamento);

		// Envia email apos o cadastramento de um estacionamento novo
		if (this.destino.equals("estacionamentoSucesso")) {

			try {

				usuarioRN.enviarEmailPosCadastramento(this.usuario);

			} catch (RNException e) {

				FacesMessage facesMessage = new FacesMessage(
						"Não foi possível enviar o e-mail de cadStringastro do estacioanamento. Erro"
								+ e.getMessage());
				context.addMessage(null, facesMessage);

				return destino;

			}

		}

		complemento = null;
		cep = null;
		this.cnpj = null;
		numero = null;
		estacionamento = new Estacionamento();
		prim_telefone = new Telefone();
		endereco = new Endereco();
		usuario = new Usuario();
		estacionamento = new Estacionamento();

		return destino;
	}

	public boolean getValidaCnpj() {

		ValidaCPFCNPJ cnpjValida = new ValidaCPFCNPJ();
		if (!cnpjValida.isValidCNPJ(cnpjValida.noFormatCNPJ(cnpj)))
			return false;

		return true;

	}

	public String consultaCep() {

		this.endereco = new Endereco();
		this.endereco = consultaEnderecoCep();
		return "estacionamento";
	}

	public Endereco consultaEnderecoCep() {

		Cep cepConsultado = new Cep();
		CepRN cepRN = new CepRN();
		Endereco end = new Endereco();
		cepConsultado = cepRN.consultaCep(this.cep);

		if (!(cepConsultado != null)) {

			FacesContext context = FacesContext.getCurrentInstance();
			FacesMessage facesMessage = new FacesMessage(
					FacesMessage.SEVERITY_ERROR,
					"Nenhum endereço encontrado para este CEP.",
					"Informe um CEP válido para o consulta.");
			context.addMessage(null, facesMessage);
			return null;
		}

		end.setCep(cepConsultado.getCep());
		end.setLogradouro(cepConsultado.getTipo_logradouro() + " "
				+ cepConsultado.getLogradouro());
		end.setBairro(cepConsultado.getBairro());
		end.setCidade(cepConsultado.getCidade());
		end.setUf("SP");

		return end;
	}

	public String definirRegra() {

		Usuario usuarioLogado = new Usuario();
		ContextoBean context = ContextoUtil.getContextoBean();
		usuarioLogado = context.getUsuarioLogado();

		ValidaCPFCNPJ validaCnpj = new ValidaCPFCNPJ();
		Long cnpjCosultado = validaCnpj.parseLongCnpj(usuarioLogado.getCpf());

		EstacionamentoRN estacioanamentoRN = new EstacionamentoRN();
		this.estacionamento = estacioanamentoRN.buscarPorCNPJ(cnpjCosultado);

		List<Estacionamento> lista = new ArrayList<Estacionamento>();
		lista.add(this.estacionamento);
		this.lista = lista;

		return "regra";

	}

	public String meuCadastro() {

		Usuario usuarioLogado = new Usuario();
		ContextoBean context = ContextoUtil.getContextoBean();
		usuarioLogado = context.getUsuarioLogado();

		ValidaCPFCNPJ validaCnpj = new ValidaCPFCNPJ();
		Long cnpjCosultado = validaCnpj.parseLongCnpj(usuarioLogado.getCpf());

		EstacionamentoRN estacioanamentoRN = new EstacionamentoRN();
		this.estacionamento = estacioanamentoRN.buscarPorCNPJ(cnpjCosultado);

		this.endereco = new Endereco();
		this.prim_telefone = new Telefone();

		endereco = this.estacionamento.getEndereco();
		prim_telefone = this.estacionamento.getTelefone();

		this.numero = String.valueOf(endereco.getNumero());
		this.complemento = endereco.getComplemento();
		this.cep = endereco.getCep();
		this.cnpj = String.valueOf(this.estacionamento.getCpfcnpj());
		this.telefone = prim_telefone.getNum_telefone();
		this.enderecoEstac = endereco.getLogradouro() + ", " + this.numero
				+ " " + this.complemento + " - " + endereco.getBairro() + ", "
				+ endereco.getUf() + ", " + this.cep;

		List<Estacionamento> lista = new ArrayList<Estacionamento>();
		lista.add(this.estacionamento);
		this.lista = null;
		this.lista = lista;

		// R. Vital Brasil - Vila Maria Augusta, Itaquaquecetuba - São Paulo,
		// 08570-310
		return "cadastro";

	}

	public void statusVagas() {

		String statusFormatado = atualizarStatus();
		int statusInt = Integer.valueOf(statusFormatado);
		
		if (statusInt != statusAnterior){
			
			this.statusAnterior = statusInt;
			
			if (statusInt == 0){
				
				this.livre ++;
				this.ocupada --;
				
			} else {

				this.livre --;
				this.ocupada ++;
				
			}
		
			
		}
		
		
		

	}

	private String atualizarStatus() {

		EstacionamentoRN estacionamentoRN = new EstacionamentoRN();
		String status = estacionamentoRN.statusVagas();
		String statusFormatado = status.replace("\n", "");

		return statusFormatado;
	}

	public void atualizarViewComStatus() {

	}

	public String alterarSenha() {

		FacesContext context = FacesContext.getCurrentInstance();
		ContextoBean contextBean = ContextoUtil.getContextoBean();

		Usuario usuarioLogado = new Usuario();
		usuarioLogado = contextBean.getUsuarioLogado();
		String senha = this.usuario.getSenha();

		if (senha != null && senha.trim().length() > 0
				&& !senha.equals(this.confirmarSenha)) {

			FacesMessage facesMessage = new FacesMessage(
					"A senha não foi confirmada corretamente");
			context.addMessage(null, facesMessage);

			return null;
		}

		if (senha != null && senha.trim().length() == 0) {

			this.usuario.setSenha(this.senhaCriptografada);

		} else {

			try {

				String senhaCripto = CriptografiaUtil.criptografar(senha);
				this.usuario.setSenha(senhaCripto);

			} catch (NoSuchAlgorithmException e) {

				FacesMessage facesMessage = new FacesMessage(
						"Não foi possível criptografar a senha do usuário. Erro: "
								+ e.getMessage());
				context.addMessage(null, facesMessage);
				return null;
			}

		}

		UsuarioRN usuarioRN = new UsuarioRN();
		usuarioLogado.setSenha(usuario.getSenha());
		usuarioRN.salvar(usuarioLogado);

		FacesMessage facesMessage = new FacesMessage(
				"Sua senha foi alterada com sucesso ! ");
		context.addMessage(null, facesMessage);

		return "meuEstacionamento";

	}

	public String editar() {

		// this.senhaCriptografada = this.usuario.getSenha();

		this.endereco = new Endereco();
		this.prim_telefone = new Telefone();
		this.usuario = new Usuario();

		endereco = this.estacionamento.getEndereco();
		usuario = this.estacionamento.getUsuario();
		prim_telefone = this.estacionamento.getTelefone();

		this.numero = String.valueOf(endereco.getNumero());
		this.complemento = endereco.getComplemento();
		this.cep = endereco.getCep();
		this.cnpj = String.valueOf(this.estacionamento.getCpfcnpj());
		// this.confirmarSenha = usuario.getSenha();

		return "cadastro";
	}

	public void excluir() {
		EstacionamentoRN estacionamentoRN = new EstacionamentoRN();
		estacionamentoRN.excluir(estacionamento);

	}

	public Usuario getUsuario() {
		return usuario;
	}

	public void setUsuario(Usuario usuario) {
		this.usuario = usuario;
	}

	public String getConfirmarSenha() {
		return confirmarSenha;
	}

	public void setConfirmarSenha(String confirmarSenha) {
		this.confirmarSenha = confirmarSenha;
	}

	public String getCep() {
		return cep;
	}

	public void setCep(String cep) {
		this.cep = cep;
	}

	public String getCnpj() {
		return cnpj;
	}

	public void setCnpj(String cnpj) {
		this.cnpj = cnpj;
	}

	public Endereco getEndereco() {
		return endereco;
	}

	public void setEndereco(Endereco end) {
		endereco = end;
	}

	public Estacionamento getEstacionamento() {
		return estacionamento;
	}

	public void setEstacionamento(Estacionamento estacionamento) {
		this.estacionamento = estacionamento;
	}

	public Telefone getPrim_telefone() {
		return prim_telefone;
	}

	public void setPrim_telefone(Telefone prim_telefone) {
		this.prim_telefone = prim_telefone;
	}

	public String getNumero() {
		return numero;
	}

	public void setNumero(String numero) {
		this.numero = numero;
	}

	public String getComplemento() {
		return complemento;
	}

	public void setComplemento(String complemento) {
		this.complemento = complemento;
	}

	public List<Estacionamento> getLista() {
		return lista;
	}

	public void setLista(List<Estacionamento> lista) {
		this.lista = lista;
	}

	public String getDestino() {
		return destino;
	}

	public void setDestino(String destino) {
		this.destino = destino;
	}

	public String getSenhaCriptografada() {
		return senhaCriptografada;
	}

	public void setSenhaCriptografada(String senhaCriptografada) {
		this.senhaCriptografada = senhaCriptografada;
	}

	public String getEnderecoEstac() {
		return enderecoEstac;
	}

	public void setEnderecoEstac(String enderecoEstac) {
		this.enderecoEstac = enderecoEstac;
	}

	public String getTelefone() {
		return telefone;
	}

	public void setTelefone(String telefone) {
		this.telefone = telefone;
	}

	public Integer getTotalVaga() {
		return totalVaga;
	}

	public void setTotalVaga(Integer totalVaga) {
		this.totalVaga = totalVaga;
	}

	public Integer getOcupadas() {
		return ocupadas;
	}

	public void setOcupadas(Integer ocupadas) {
		this.ocupadas = ocupadas;
	}

	public Integer getLivres() {
		return livres;
	}

	public void setLivres(Integer livres) {
		this.livres = livres;
	}

	public boolean isModalVaga() {
		return modalVaga;
	}

	public void setModalVaga(boolean modalVaga) {
		this.modalVaga = modalVaga;
	}

	public int getLivre() {
		return livre;
	}

	public void setLivre(int livre) {
		this.livre = livre;
	}

	public int getOcupada() {
		return ocupada;
	}

	public void setOcupada(int ocupada) {
		this.ocupada = ocupada;
	}

	public int getStatusAnterior() {
		return statusAnterior;
	}

	public void setStatusAnterior(int statusAnterior) {
		this.statusAnterior = statusAnterior;
	}

}